.model small
.data
	evidencija db 16000 DUP (0)
	eviPos dw evidencija
	
	;iscrtavanje
	 Display_message0 db     "   -   | |       | |   - "
	 Display_message1 db     "        /|         |     "
	 Display_message2 db     "   -     |   -   |     - "
	 Display_message3 db     "   -     |   -     |   - "
	 Display_message4 db     "       | |   -     |     "
	 Display_message5 db     "   -   |     -     |   - "
	 Display_message6 db     "   -   |     -   | |   - "
	 Display_message7 db     "   -   | |         |     "
	 Display_message8 db     "   -   | |   -   | |   - "
	 Display_message9 db     "   -   | |   -     |   - "
	
	 Display_messageA db     " - - |   | - - |   |     "
	 Display_messageB db     " - -   | |   _   | | - - "
	 Display_messageC db     " - - |         |     - - "
	 Display_messageD db     " - -   | |       | | - - "
	 Display_messageE db     " - - |     - - |     - - "
	 Display_messageF db     " - - |     - - |         "
	 Display_messageG db     " - - |       - |   | - - "
	 Display_messageH db     "     |   | - - |   |     "
	 Display_messageI db     " - -   |         |   - - "
	 Display_messageJ db     "         |       | |   - "
	
	 Display_messageK db     "     |  /  -   |  \      "
	 Display_messageL db     "     |         |     - - "
	 Display_messageM db     "     |\ /|     |   |     "
	 Display_messageN db     "     |\  |     |  \|     "
	 Display_messageO db     " - - |   |     |   | - - "
	 Display_messageP db     " - - |   | - - |         "
	 Display_messageR db     " - - |   | - - |  \      "
	 Display_messageS db     " - - |     - -     | - - "
	 Display_messageT db     " - -   |         |       "
	 Display_messageU db     "     |   |     |   | - - "
	 Display_messageV db     "     |   |      \ /      "
	 Display_messageZ db     " - -    /       /    - - "
	 Display_messageX db     "      \ /       / \      "
	 Display_messageSpace db     "                         "
	 Display_messageDash db     "           - -           "
	 Display_messageStar db     "      \|/  - -  /|\      "
	
	String_Rezultat db '          $'
	String_Radni db "                                        "
	String_Ulazni db "                              "
	tempCena dw 0
	brojUnosa dw 1000
	
	;poruka za ispis
	Diplay_Poruka db '                $'
	
	Display_Programiranje db "programiranje   "
	Display_Funkcija      db "Funkcija        "
	Display_Cekam 		db "Cekam           "
	Display_Greska			db "greska          "
	
	msgSignature db "Maxisim - by Vladimir Mihajlovski 129/07 & Djordje Maksimovic 215/07"
	msgSigSeparator db "--------------------------------------------------------------------------------"
	
	
	genImeProizvoda db "Item        "
	imeProizvoda db "123456789ABC"
	jedinicnaCena dw 0
	kolicina dw 0
	trenutniRacun dw 0
	totalniPromet dw 0
	trazenaSifra dw 0
	trazenaSifraStara dw 0
	boolRacun dw 0 ; da li je otpocet racun
	
	
	FALSE equ 00h
	TRUE equ 01h
	CLOCK_HOURS db 0	
	CLOCK_MINUTES db 0
	CLOCK_SECONDS db 0
	boolDisplayTime db 1
	
	stanje db 0
	stanje_staro db 0
	stanje_cekam equ 00h
	stanje_unos_stavki equ 01h
	stanje_unos_naziva equ 02h
	stanje_unos_cene equ 03h
	stanje_unos_vremena equ 04h
	stanje_spreman equ 05h
	stanje_unos_sifre equ 06h
	stanje_unos_kolicine equ 07h
	stanje_racun equ 08h
	stanje_funkcija equ 09h
	stanje_error equ 0Ah
	stanje_zauzet equ 0Bh
	stanje_ispis_promet equ 0Ch
	
	
	msgConst0 db '0$'
	msgConstDash db '-$'
	
	old_timer_routine	dw 2 dup (0)
	ticks_in_timer_count db 0
	
	printer_message00 db "                    "
	printer_message01 db "                    "
	printer_message02 db "                    "
	printer_message03 db "                    "
	printer_message04 db "                    "
	printer_message05 db "                    "
	printer_message06 db "                    "
	printer_message07 db "                    "
	printer_message08 db "                    "
	printer_message09 db "                    "
	printer_message10 db "                    "
	printer_message11 db "                    "
	printer_message12 db "                    "
	printer_message13 db "                    "
	printer_message14 db "                    "
	printer_messageWidth dw 20 
	printer_messageEmpty db "                    "
	printer_messageSeparator db "===================="
	printer_messageTemp db "                    "
	
	serial_message00 db 40 dup (32)
	serial_message01 db 40 dup (32)
	serial_message02 db 40 dup (32)
	serial_message03 db 40 dup (32)
	serial_message04 db 40 dup (32)
	serial_message05 db 40 dup (32)
	serial_message06 db 40 dup (32)
	serial_message07 db 40 dup (32)
	serial_message08 db 40 dup (32)
	serial_message09 db 40 dup (32)
	serial_message10 db 40 dup (32)
	serial_message11 db 40 dup (32)
	serial_message12 db 40 dup (32)
	serial_message13 db 40 dup (32)
	serial_message14 db 40 dup (32)
	serial_messageWidth equ 40
	serial_messageEmpty db 		"                                        "
	serial_messageConnect db 	"<< Konekcija                            "
	serial_messageConnectOK db 	">> Konekcija uspostavljena              "
	serial_messageSet db 		">> Primljeno:                           "
	serial_messageSetTime db     ">> Primljeno vreme                      "
	serial_messageDisconnect db 	">> Diskonekcija                         "
	serial_messageDisconnectOK db 	"<< Konekcija ugasena                    "
	serial_messageConnectToPC db 	"<< Konekcija                            "
	serial_messageConnectToPCOK db 	">> Konecija uspostavljena               "
	serial_messageDisconnectToPC db 	"<< Diskonekcija                         "
	serial_messageDisconnectToPCOK db 	">> Konekcija ugasena                    "
	
	serial_messageSend db 		'<< Slanje:                              '
	serial_messageSendOK db 		'>> Prihvaceno                           '
	
	serial_messageTemp db 		"                                        "
	
	
	charExit equ 1Bh ; ESC - izlazak iz simulatora
	
.stack 256h
.code

;*************************************************************************
;Timer_init - menjanje prekidne rutine tajmera (ulaz 1Ch)
; stara prekidna rutina cuva se old_timer_routine
;		Input:  n/a
;		Output: n/a
;*************************************************************************

Timer_init proc far
	push ax
	push es
	
	;ES = segment IVT
	mov ax, 0000h					
	mov es, ax
	;offset stare prekidne rutine
	mov ax, es:[1Ch*4]				
	mov word ptr old_timer_routine, ax
	;segment stare prekidne rutine
	mov ax, es:[1Ch*4 + 2]
	mov word ptr old_timer_routine+2, ax

	cli	;onemogucavaju se prekidi jer se snima u IVT
	mov word ptr es:[1Ch*4], offset new_timer_routine	;snimanje ofseta nove prekidne rutine u IVT
	mov word ptr es:[1Ch*4 + 2], seg new_timer_routine	;snimanje segmenta nove prekidne rutine u IVT
	sti	;ponovo su omoguceni prekidi

	pop es
	pop ax
	
	retf
Timer_init endp


;*************************************************************************
;Timer_deinit - vracanje adrese originalne prekidne rutine tajmera
;		Input:  n/a
;		Output: n/a
;*************************************************************************
Timer_deinit proc far
	push ax
	push es
	push ds
	
	;ES = segment IVT
	mov ax, 0000h
	mov es, ax
	cli		;onemogucavaju se prekidi dok se snima u IVT
	mov ax, word ptr old_timer_routine
	mov es:[1Ch*4], ax
	mov ax, word ptr old_timer_routine+2
	mov es:[1Ch*4+2], ax
	sti    ;omogucavanje prekida
	
	pop ds
	pop es
	pop ax

	retf
Timer_deinit endp

;********************************************************************************
; ProgramLoop - glavna petlja programa
;	Input: n/a
;	Output: n/a
;********************************************************************************
ProgramLoop PROC
lblReadKey:
	;!!!!!!!!!!!!!!!!!!!
	;potrebno je prvo osveziti ekran
	
	xor ax,ax
	call ReadKey
	
	cmp al, 46h ; F
	jz lblProgrammingModeFirst
	cmp al, 66h ; f
	jz lblProgrammingModeFirst
	jmp lblReadKey ; ceka se F ili f
	
lblProgrammingModeFirst:
	mov stanje, stanje_unos_stavki
	call PrintDisplay
	;hand-shake
	mov si, offset serial_messageConnect
	call AddStringToSerial
	mov si, offset serial_messageConnectOK
	call AddStringToSerial
	
lblProgrammingMode:
	mov stanje, stanje_unos_stavki 
	xor ax,ax
	;generisanje artikala
	mov cx, 0
lblGenerisanjeArtikala:	
	mov ax,cx
	call WordToString
	
	push cx 
	
	mov di, 0
	mov bx, offset String_Ulazni
	mov cx, 12
	call FlushString
	
	mov si, offset genImeProizvoda
	mov di, offset String_Ulazni
	mov bx,0
	mov cx,4
	call StringCopy
	
	
	mov si, offset String_Rezultat
	mov di, offset String_Ulazni
	mov bx,4
	mov cx,10
	call StringCopyLeft
	
	mov si, offset String_Ulazni
	mov di, eviPos
	mov bx,0
	mov cx,12
	call StringCopy
	
	
	pop cx
	inc cx
	;generisanje cene
	add di, 12
	mov [di], cx
	add di,4
	mov eviPos, di
	cmp cx,brojUnosa
	jl lblGenerisanjeArtikala
	
	
	;pauza
	call WaitWait
	
	;slanje kroz serijski
	mov si, offset serial_messageSet
	mov di, offset String_Radni
	xor bx, bx
	mov cx, serial_messageWidth
	call StringCopy
	
	mov ax, brojUnosa
	call WordToString
	
	mov si, offset String_Rezultat
	mov di, offset String_Radni
	mov bx, 14 ; pomeraj u dest
	mov dx, 6 ; pomeraj u src
	mov cx, 4 ; duzina ukupnog broja
	call StringCopyExtended
	

	
	
	; sad ubacimo u serijski red
	mov si, offset String_Radni
	call AddStringToSerial
	
	;potvrda
	;mov si, offset serial_messageSetOK
	;call AddStringToSerial
	

	
lblEnterTime:
	mov stanje, stanje_unos_vremena
	xor ax,ax
	
	;dohvatanje sistemskog vremena
	mov ah,2Ch
	int 21h
	mov CLOCK_HOURS,ch
	mov CLOCK_MINUTES,cl
	mov CLOCK_SECONDS,dh
	
	;pauza
	call WaitWait
	
	;objava
	mov si, offset serial_messageSetTime
	call AddStringToSerial
	
	;mov si, offset serial_messageSetOK
	;call AddStringToSerial
	

	
	mov si, offset serial_messageDisconnect
	call AddStringToSerial
	
	mov si, offset serial_messageDisconnectOK
	call AddStringToSerial
	
	
	;sad se ceka F, radi prekida serijskog prenosa
;lblWaitDisconnect:	
	;xor ax,ax
	;call ReadKey
	;cmp al, 46h ; F
	;jz lblPrelazakSpreman
	;cmp al, 66h ; f
	;jnz lblWaitDisconnect

;PRAVI POS'O	
lblPrelazakSpreman:
	mov stanje, stanje_spreman
	call PrintDisplay
	
	xor ax, ax
	call ReadKey
	cmp al, 46h ; F
	jz lblFunkcija
	cmp al, 66h ; f
	jz lblFunkcija
	
	;provera da li je cifra
	cmp al, 30h ; '0'
	jl lblSpremanZaGresku
	cmp al, 39h ; '9'
	jg lblSpremanZaGresku
	; skacemo na obradu sifre
	
	jmp lblPrelazakSifra
	
	
lblSpremanZaGresku:	
	call ErrorState
	jmp lblPrelazakSpreman
	
lblFunkcija:
	mov stanje, stanje_funkcija
	call PrintDisplay
	
	xor ax, ax
	call ReadKey
	cmp al, 30h ; '0'
	jz lblSlanjeSerijski
	cmp al, 31h ; '1'
	jz lblStampanjeProdatihRucka
	cmp al, 32h ; '2'
	jz lblPrometDisplej
	cmp al, 33h ; '3'
	jz lblOtvaranjeLadice
	
	;korisnik moze i da odustane
	cmp al, 43h ; C
	jz lblNecuIpakFunkciju
	cmp al, 63h ; c
	jz lblNecuIpakFunkciju
	
	;ukoliko nije 0-3 ili C, greska
	call ErrorState
	jmp lblFunkcija
	
lblStampanjeProdatihRucka:
	jmp lblStampanjeProdatih
	
lblNecuIpakFunkciju:
	jmp lblPrelazakSpreman
	
lblPrometDisplej:
	mov stanje, stanje_ispis_promet
	call PrintDisplay
	;zadrzavanje neko vreme
	call WaitWait
	
	jmp lblPrelazakSpreman
	
lblOtvaranjeLadice:
	;beep
	mov ah, 09h
	mov al, 7 ; bell character
	xor bx,bx
	int 10h
	jmp lblPrelazakSpreman
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
lblSlanjeSerijski:
	mov stanje, stanje_zauzet
	call PrintDisplay
	
	;prvo moramo ispisati poruke za hand-shaking za konekciju
	mov si, offset serial_messageConnectToPC
	call AddStringToSerial
	mov si, offset serial_messageConnectToPCOK
	call AddStringToSerial
	
	; potrebno je pronaci artikle koji su prodati vise puta
	mov si, offset evidencija
	mov di, offset evidencija
	add di, 14 ; na kolicinu
	mov cx, brojUnosa
	
lblSerijskoSlanjeLoop:
	push cx ; trebace registar u petlji, a mora se sacuvati za loop na kraju
	mov ax, [di] ; cita se kolicina
	cmp ax, 0
	jz lblSerijskoSlanjePredKraj
	
	xor bx, bx
	mov [di], bx ;upisuje se 0 u kolicinu artikla
	
	call WordToString ; kolicina
	
	mov ax, si
	mov dx, di ;backup
	
	mov si, offset serial_messageSend
	mov di, offset serial_messageTemp
	xor bx, bx
	mov cx, serial_messageWidth
	call StringCopy
	
	push dx
	mov si, offset String_Rezultat
	mov di, offset serial_messageTemp
	mov bx, 35 ; pomeraj u dst
	mov cx, 5
	mov dx, 5 ; pomeraj u src
	call StringCopyExtended
	pop dx
	
	mov si, ax ; ime proizvoda
	mov di, offset serial_messageTemp
	mov bx, 12
	mov cx, 12
	call StringCopy
	
	;pauza
	call WaitWait
	
	;hand shaking
	mov si, offset serial_messageTemp
	call AddStringToSerial
	
	;mov si, offset serial_messageSendOK
	;call AddStringToSerial
	
	mov si, ax
	mov di, dx	
	
lblSerijskoSlanjePredKraj:
	add si, 16
	add di, 16 ;pomeranje na sledeci artikal
	
	pop cx
	loop lblSerijskoSlanjeLoop
	
	;sad se treba diskonektovati
	mov si, offset serial_messageDisconnectToPC
	call AddStringToSerial
	mov si, offset serial_messageDisconnectToPCOK
	call AddStringToSerial
	
	jmp lblPrelazakSpreman

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lblStampanjeProdatih:
	mov stanje, stanje_zauzet
	call PrintDisplay
	
	mov si, offset evidencija
	mov di, offset evidencija
	add di, 14 ;broj prodatih
	mov cx, brojUnosa
	
lblStampanjeProdLoop:
	push cx ; trebace nam registar, pa da se sacuva za iteriranje
	
	mov ax, [di] ; citamo kolicinu
	
	cmp ax, 0
	jz lblStampanjePredKrajLoopa
	
	xor bx, bx
	mov [di], bx ; upisujemo 0
	
	call WordToString ;kolicina
	
	mov ax, si ;backup
	mov dx, di
	;kolicina s desne strane
	mov si, offset String_Rezultat
	mov di, offset printer_messageTemp
	mov bx, 10 ; pomeraj u dest
	mov cx, 10
	call StringCopy
	
	;ime proizvoda s leve
	mov si, ax ; u ax se nalazi pomeraj evidencije
	mov di, offset printer_messageTemp
	xor bx, bx
	mov cx, 12
	call StringCopy
	
	mov printer_messageTemp[12], ':'
	
	;pauza
	call WaitWait
	
	mov si, offset printer_messageTemp
	call AddStringToBill
	
	;povratak iz backupa
	mov si, ax
	mov di, dx
		
lblStampanjePredKrajLoopa:
	add si, 16
	add di, 16 ;pomeranje na sledeci artikal
	
	pop cx ; bio je sacuvan na pocetku petlje
	loop lblStampanjeProdLoop
	
	; 3 prazna reda
	mov si, offset printer_messageEmpty
	call AddStringToBill
	call AddStringToBill
	call AddStringToBill	
	
	jmp lblPrelazakSpreman
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
lblPrelazakSpremanSifraRucka:
	jmp lblPrelazakSpreman

	
lblPrelazakSifra:
	sub al, 30h ; sad je broj
	xor ah,ah
	cmp ax, brojUnosa
	jl lblSifraOpsegOKRanije
	call ErrorState
	cmp stanje, stanje_spreman
	je lblPrelazakSpremanSifraRucka
	jmp lblPrelazakRacun
	
lblPrelazKolicinaRucka:
	jmp lblPrelazKolicina
	
lblSifraTarabaRucka:
	jmp lblSifraTaraba

lblSifraOpsegOKRanije:	
	mov trazenaSifraStara, 0
	mov trazenaSifra, ax
	mov kolicina, 1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
lblSifraOpsegOK:
	;pronaci podatke o proizvodu
	mov stanje, stanje_unos_sifre
	call SearchRecords
	call PrintDisplay
	
	; treba obaviti citanje karaktera i dalju akciju 
lblSifraPetlja:
	xor ax, ax
	call ReadKey
	;pre cifri proveriti ostalo
	cmp al, 43h ; C
	jz lblSifraOdustajanje
	cmp al, 63h ; c
	jz lblSifraOdustajanje
	cmp al, 2Bh ; +
	jz lblSifraPlus
	cmp al, 23h ; #
	jz lblSifraTarabaRucka
	cmp al, 2Ah ; *
	jz lblPrelazKolicinaRucka
	cmp al, 30h ; '0'
	jl lblSifraGreska
	cmp al, 39h ; '9'
	jg lblSifraGreska
	;cifra je
	
	xor ah, ah ; visi deo nije bitan
	sub al, 30h ; atoi
	mov cx, ax ; sacuvati cifru jedinicu
	mov ax, trazenaSifra 
	mov trazenaSifraStara, ax ;sacuvati staru u slucaju greske
	mov bx, 10 ; pomnoziti staru sifru sa 10 i dodati novu cifru
	mul bx
	add ax, cx
	mov trazenaSifra, ax
	
	cmp ax, brojUnosa
	jl lblSifraOpsegOK
	call ErrorState
	call PrintDisplay
	jmp lblSifraPetlja

lblSifraGreska:
	call ErrorState
	call PrintDisplay
	jmp lblSifraPetlja
	
lblSifraOdustajanje:
	mov dx, boolRacun
	cmp dx, 0
	je lblPrelazakSpremanSifOduRucka
	jmp lblPrelazakRacun
	
lblPrelazakSpremanSifOduRucka:
	jmp lblPrelazakSpreman
	
lblSifraPlus:
	mov ax, jedinicnaCena
	mul kolicina
	add trenutniRacun, ax ;dodajemo cenu na vrednost racuna
	
	
	; da ocistimo radni string
	mov si, offset printer_messageEmpty
	mov di, offset printer_messageTemp
	xor bx, bx
	mov cx, printer_messageWidth
	call StringCopy
	
	;izgled stavke:
	;ime proizvoda
	;(-)kolicina x jed. cena
	mov si, offset imeProizvoda
	mov di, offset printer_messageTemp
	xor bx, bx
	mov cx, 12
	call StringCopy
	
	mov si, offset printer_messageTemp
	call AddStringToBill
	
	; da ocistimo radni string
	mov si, offset printer_messageEmpty
	mov di, offset printer_messageTemp
	xor bx, bx
	mov cx, printer_messageWidth
	call StringCopy
	
	mov ax, kolicina
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset printer_messageTemp
	mov bx, 1 ; prvo mesto je rezervisano za eventualni minus
	mov cx, 10 ;mada nece biti ovoliko
	call StringCopyLeft ; zanemaruju se blanko znaci, ne bi li bilo poravnato sa levom ivicom
	
	mov ax, jedinicnaCena
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset printer_messageTemp
	mov bx, 10
	mov cx, 10
	call StringCopy
	
	mov printer_messageTemp[10], 'x'
	
	mov si, offset printer_messageTemp
	call AddStringToBill
	
	mov si, trazenaSifra
	shl si, 4 ; * 16 (duzina jedne evidencije u B)
	add si, offset evidencija
	add si, 14 ; pozicioniranje na do tad potrosene kolicine
	mov ax, [si]
	add ax, kolicina
	mov [si], ax ; upisivanje azurirane vrednosti
	
	mov trazenaSifra, 0
	jmp lblPrelazakRacun
	
lblSifraTaraba:
;izuzetno slicno kao i '+'
	mov ax, jedinicnaCena
	mul kolicina
	sub trenutniRacun, ax ;ovde oduzimamo cenu na vrednost racuna
	
	
	; da ocistimo radni string
	mov si, offset printer_messageEmpty
	mov di, offset printer_messageTemp
	xor bx, bx
	mov cx, printer_messageWidth
	call StringCopy
	
	;izgled stavke:
	;ime proizvoda
	;(-)kolicina x jed. cena
	mov si, offset imeProizvoda
	mov di, offset printer_messageTemp
	xor bx, bx
	mov cx, 12
	call StringCopy
	
	mov si, offset printer_messageTemp
	call AddStringToBill
	
	; da ocistimo radni string
	mov si, offset printer_messageEmpty
	mov di, offset printer_messageTemp
	xor bx, bx
	mov cx, printer_messageWidth
	call StringCopy
	
	mov ax, kolicina
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset printer_messageTemp
	mov bx, 1 ; prvo mesto je rezervisano za eventualni minus
	mov cx, 10 ;mada nece biti ovoliko
	call StringCopyLeft ; zanemaruju se blanko znaci, ne bi li bilo poravnato sa levom ivicom
	
	mov ax, jedinicnaCena
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset printer_messageTemp
	mov bx, 10
	mov cx, 10
	call StringCopy
	
	mov printer_messageTemp[10], 'x'
	mov printer_messageTemp[0], '-' ;u ovom slucaju potreban je predznak
	
	mov si, offset printer_messageTemp
	call AddStringToBill
	
	mov si, trazenaSifra
	shl si, 4 ; * 16 (duzina jedne evidencije u B)
	add si, offset evidencija
	add si, 14 ; pozicioniranje na do tad potrosene kolicine
	mov ax, [si]
	sub ax, kolicina
	mov [si], ax ; upisivanje azurirane vrednosti
	
	mov trazenaSifra, 0
	jmp lblPrelazakRacun

lblPrelazKolicina:
	mov kolicina, 0
lblKolicinaPetlja:
	mov stanje, stanje_unos_kolicine
	
	xor ax, ax
	call ReadKey
	cmp al, 43h ; C
	jz lblKolicinaBrisanje
	cmp al, 63h ; c
	jz lblKolicinaBrisanje
	cmp al, 2Bh ; +
	jz lblKolicinaPlus
	cmp al, 23h ; #
	jz lblKolicinaTaraba
	cmp al, 30h ; '0'
	jl lblKolicinaGreska
	cmp al, 39h ; '9'
	jg lblKolicinaGreska
	;cifra je
	
	;potrebno je pomeriti ulevo cifre i dodati novu
	xor ah, ah
	sub al, 30h ; - '0'
	push ax
	mov ax, kolicina
	mov bx, 10
	mul bx
	mov bx, ax
	pop ax
	add ax, bx
	mov kolicina, ax ; vracamo rezultat u kolicinu
	
	call PrintDisplay
	jmp lblKolicinaPetlja
	
lblKolicinaBrisanje:
	mov kolicina, 0
	call PrintDisplay
	jmp lblKolicinaPetlja

;postupak je isti, te se moze koristiti isti kod
lblKolicinaPlus:
	jmp lblSifraPlus

lblKolicinaTaraba:
	jmp lblSifraTaraba
	
lblKolicinaGreska:
	call ErrorState
	call PrintDisplay
	jmp lblKolicinaPetlja
	
lblPrelazakRacun:
;treba zapoceti racun ukoliko nije zapocet, i cekati = ili novu sifru
	mov boolRacun, 1
	mov stanje, stanje_racun
	call PrintDisplay
	xor ax, ax
	call ReadKey
	cmp al, 3Dh ; '='
	jz lblGotovRacun
	cmp al, 30h ; '0'
	jl lblRacunGreska
	cmp al, 39h ; '9'
	jg lblRacunGreska
	jmp lblPrelazakSifra
	
lblRacunGreska:
	call ErrorState
	jmp lblPrelazakRacun
	
lblGotovRacun:
	;odstampati kraj racuna, dodati totalni promet
	mov ax, trenutniRacun
	add totalniPromet, ax
	
	mov si, offset printer_messageSeparator
	call AddStringToBill
	
	;ocistiti radni string
	mov bx, offset printer_messageTemp
	mov cx, printer_messageWidth
	call FlushString
	
	mov ax, trenutniRacun
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset printer_messageTemp
	mov bx, 10 ; dst pomeraj
	mov cx, 10 ; duzina
	call StringCopy
	
	mov si, offset printer_messageTemp
	call AddStringToBill
	
	; 3 reda razmaka
	mov si, offset printer_messageEmpty
	call AddStringToBill
	call AddStringToBill
	call AddStringToBill
	
	;ponistavanje racuna
	mov trenutniRacun, 0
	mov boolRacun, 0
	;vratiti se u stanje spreman
	jmp lblPrelazakSpreman
	
	
	
	
	
	
	
ProgramLoop ENDP

;********************************************************************************
; ErrorState - funkcija koja ubacuje program u stanje greske i ceka C
;	Input: N/A
;   Output: N/A
;********************************************************************************
ErrorState PROC
	push ax
	;potrebno je sacuvati staro stanje, radi vracanja sistema na prethodno stanje
	mov al, stanje
	mov stanje_staro, al
	mov stanje, stanje_error
	;ispis greske
	call PrintDisplay
lblWaitForCKey:
	;cekanje da se pritisne C ili c
	xor ax, ax
	call ReadKey
	cmp al, 43h ; C
	jz lblCKeyHere
	cmp al, 63h ; c
	jnz lblWaitForCKey
lblCKeyHere:
	mov al, stanje_staro
	mov stanje, al
	call PrintDisplay
	pop ax
	ret
	

ErrorState ENDP


;********************************************************************************
;	PrintDisplay - ispisuje sadrzaj sa Diplay_Poruka na displayu
;		Input : 	
;		Output :	
;********************************************************************************
PrintDisplay PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	mov al, stanje
	cmp al, stanje_cekam
	jz lblPrintCekam
	
	cmp al, stanje_unos_stavki
	jz lblPrintProgramiranje
	cmp al, stanje_unos_naziva
	jz lblPrintProgramiranje
	cmp al, stanje_unos_cene
	jz lblPrintProgramiranje
	cmp al, stanje_unos_vremena
	jz lblPrintProgramiranje
	cmp al, stanje_spreman
	jz lblPrintSpreman
	cmp al, stanje_funkcija
	jz lblPrintFunkcija
	cmp al, stanje_zauzet
	jz lblPrintZauzet
	cmp al, stanje_error
	jz lblPrintGreskaRucka
	cmp al, stanje_ispis_promet
	jz lblPrintPrometRucka
	cmp al, stanje_unos_sifre
	jz lblPrintSifraRucka
	cmp al, stanje_racun
	jz lblPrintRacunRucka
	cmp al, stanje_unos_kolicine
	jz lblPrintKolicinaRucka
	
	jmp lblprintend

lblPrintGreskaRucka:
	jmp lblPrintGreska
	
lblPrintPrometRucka:
	jmp lblPrintPromet
	
lblPrintRacunRucka:
	jmp lblPrintRacun

lblPrintKolicinaRucka:
	jmp lblPrintKolicina
	
lblPrintSifraRucka:
	jmp lblPrintSifra
	
lblPrintCekam:
	;prvo ocistimo, pa unesemo
	mov bx, offset Diplay_Poruka
	mov cx, 16
	call FlushString
	
	mov si, offset Display_Cekam
	mov di, offset Diplay_Poruka
	mov bx, 3
	mov cx, 13
	call StringCopy
	jmp lblRealPrint
	
lblPrintProgramiranje:
	mov bx, offset Diplay_Poruka
	mov cx, 16
	call FlushString
	
	mov si, offset Display_Programiranje
	mov di, offset Diplay_Poruka
	mov bx, 3
	mov cx, 13
	call StringCopy
	jmp lblRealPrint
	
lblPrintSpreman:
	;potrebno je ispisati vreme
	call SendTimeToDisplayString
	jmp lblRealPrint
	
lblPrintFunkcija:
;ispisacemo "funkcija"
	mov bx, offset Diplay_Poruka
	mov cx, 16
	call FlushString
	
	mov si, offset Display_Funkcija
	mov di, offset Diplay_Poruka
	mov bx, 3
	mov cx, 13
	call StringCopy
	jmp lblRealPrint

lblPrintZauzet:	
;vreme i *
	call SendTimeToDisplayString
	mov byte ptr Diplay_Poruka[15],'*'
	jmp lblRealPrint
	
lblPrintGreska:
;greska
	mov bx, offset Diplay_Poruka
	mov cx, 16
	call FlushString
	
	mov si, offset Display_Greska
	mov di, offset Diplay_Poruka
	mov bx, 3
	mov cx, 13
	call StringCopy
	jmp lblRealPrint
	
lblPrintPromet:
;ispis dosadasnjeg prometa na displeju
	
	mov bx, offset Diplay_Poruka
	mov cx, 16
	call FlushString
	
	mov ax, totalniPromet
	call WordToString
	;rezultat je u String_Rezultat
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 3
	mov cx, 10
	call StringCopyLeft
	jmp lblRealPrint
	
lblPrintSifra:
;ispis naziva i cene artikla
	push ax
	mov ax, 1 ; kolicina
	; prvo cena krajnje desno
	mul word ptr jedinicnaCena
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 6
	mov cx, 10
	call StringCopy
	; naziv na levoj strani
	mov si, offset imeProizvoda
	xor bx, bx
	mov cx, 12 ; duzina naziva, maksimalna
	call StringCopy
	pop ax
	jmp lblRealPrint
	
lblPrintRacun:
;ispis vrednosti trenutnog racuna
	mov bx, offset Diplay_Poruka
	mov cx, 16
	call FlushString
	
	push ax
	mov ax, trenutniRacun
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 6
	mov cx, 10
	call StringCopy
	cmp ax, 0
	jge lblRacunPozitivan
	mov Diplay_Poruka[0], '-'
lblRacunPozitivan:
	pop ax
	jmp lblRealPrint
	
lblPrintKolicina:
;potrebno je ispisati kolicinu levo, i vrednost desno
	mov bx, offset Diplay_Poruka
	mov cx, 16
	call FlushString
	
	push ax
	mov ax, kolicina ; kolicina * jedinicna cena u desnom
	mul word ptr jedinicnaCena
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 6 ;pomeraj u dst
	mov cx, 10 ; cnt
	call StringCopy
	
	mov ax, kolicina
	call WordToString
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 0
	mov cx, 10
	call StringCopyLeft ;pomereno u levo
	
	pop ax
	jmp lblRealPrint
	
	
;priprema za ispis	
lblRealPrint:
	lea di, Diplay_Poruka
	mov cx, 16
	mov dx, 0
	xor ax, ax
	
;odredjivanje ascii karaktera	

;!!!!!!!!!!!!!!!!!!!!!
;zbog offseta pri skokovima mora da bude spageti kod
lblwritetextondisplay:
	mov al, [di]
	inc di
	
	cmp al, 32 ; ascii space
	jz lblwtdSpace
	;cifra
	cmp al, 48 ; ascii nula
	jz lblwtd0
	
	cmp al, 49 ; ascii 1
	jz lblwtd1
	
	cmp al, 50
	jz lblwtd2
	
	cmp al, 51
	jz lblwtd3
	
	cmp al, 52
	jz lblwtd4
	
	cmp al, 53
	jz lblwtd5
	
	cmp al, 54
	jz lblwtd6
	
	cmp al, 55
	jz lblwtd7
	
	cmp al, 56
	jz lblwtd8
	
	cmp al, 57  ;; broj 9
	jz lblwtd9
	
	jmp lblCompareLetters
	
		;kopiranje matrice karaktera za ispis
lblwtdSpace:
	lea si,  Display_messageSpace
	jmp lblwtdprint
	
lblwtd0:
	lea si,  Display_message0
	jmp lblwtdprint
	
lblwtd1:
	lea si,  Display_message1
	jmp lblwtdprint
	
lblwtd2:
	lea si,  Display_message2
	jmp lblwtdprint
	
lblwtd3:
	lea si,  Display_message3
	jmp lblwtdprint

lblwtd4:
	lea si,  Display_message4
	jmp lblwtdprint

lblwtd5:
	lea si,  Display_message5
	jmp lblwtdprint

lblwtd6:
	lea si,  Display_message6
	jmp lblwtdprint

lblwtd7:
	lea si,  Display_message7
	jmp lblwtdprint

lblwtd8:
	lea si,  Display_message8
	jmp lblwtdprint

lblwtd9:
	lea si,  Display_message9
	jmp lblwtdprint
	
	; sad slova: i mala i velika:
	
lblCompareLetters:
	cmp al, 45  ;; minus: -
	jz lblwtdDash
	
	cmp al, 42  ;; star
	jz lblwtdStar
	
	cmp al, 65
	jz lblwtdA
	cmp al, 97
	jz lblwtdA
	
	cmp al, 66
	jz lblwtdB
	cmp al, 98
	jz lblwtdB
	
	cmp al, 67
	jz lblwtdC
	cmp al, 99
	jz lblwtdC

	cmp al, 68
	jz lblwtdD
	cmp al, 100
	jz lblwtdD
	
	cmp al, 69
	jz lblwtdE
	cmp al, 101
	jz lblwtdE
	
	cmp al, 70
	jz lblwtdF
	cmp al, 102
	jz lblwtdF
	
	cmp al, 71
	jz lblwtdG
	cmp al, 103
	jz lblwtdG
	
	cmp al, 72
	jz lblwtdH
	cmp al, 104
	jz lblwtdH
	
	jmp lblCompareLettersI
	
lblwtdDash:
	lea si,  Display_messageDash
	jmp lblwtdprint
	
lblwtdStar:
	lea si,  Display_messageStar
	jmp lblwtdprint
	
lblwtdA:
	lea si,  Display_messageA
	jmp lblwtdprint
	
lblwtdB:
	lea si,  Display_messageB
	jmp lblwtdprint
	
lblwtdC:
	lea si,  Display_messageC
	jmp lblwtdprint
	
lblwtdD:
	lea si,  Display_messageD
	jmp lblwtdprint
	
lblwtdE:
	lea si,  Display_messageE
	jmp lblwtdprint
	
lblwtdF:
	lea si,  Display_messageF
	jmp lblwtdprint
	
lblwtdG:
	lea si,  Display_messageG
	jmp lblwtdprint
	
lblwtdH:
	lea si,  Display_messageH
	jmp lblwtdprint
	
lblwtdI:
	lea si,  Display_messageI
	jmp lblwtdprint
	
lblwtdJ:
	lea si,  Display_messageJ
	jmp lblwtdprint
	
	
lblCompareLettersI:	
	cmp al, 73
	jz lblwtdI
	cmp al, 105
	jz lblwtdI
	
	cmp al, 74
	jz lblwtdJ
	cmp al, 106
	jz lblwtdJ
	
	cmp al, 75
	jz lblwtdK
	cmp al, 107
	jz lblwtdK
	
	cmp al, 76
	jz lblwtdL
	cmp al, 108
	jz lblwtdL
	
	cmp al, 77
	jz lblwtdM
	cmp al, 109
	jz lblwtdM
	
	cmp al, 78
	jz lblwtdN
	cmp al, 110
	jz lblwtdN
	
	cmp al, 79
	jz lblwtdO
	cmp al, 111
	jz lblwtdO
	
	cmp al, 80
	jz lblwtdP
	cmp al, 112
	jz lblwtdP
	
	cmp al, 82
	jz lblwtdR
	cmp al, 114
	jz lblwtdR
	
	cmp al, 83
	jz lblwtdS
	cmp al, 115
	jz lblwtdS
	
	cmp al, 84
	jz lblwtdT
	cmp al, 116
	jz lblwtdT
	
	cmp al, 85
	jz lblwtdU
	cmp al, 117
	jz lblwtdU
	
	cmp al, 86
	jz lblwtdV
	cmp al, 118
	jz lblwtdV
	
	cmp al, 88
	jz lblwtdX
	cmp al, 120
	jz lblwtdX
	
	cmp al, 90
	jz lblwtdZ
	cmp al, 122
	jz lblwtdZ
	;kraj slova
	
	;ukoliko nije prepoznato, zanemaruje se
	dec cx
	jz lblprintend ;kraj ispisa
	jmp lblwritetextondisplay
	

	

	
lblwtdK:
	lea si,  Display_messageK
	jmp lblwtdprint
	
lblwtdL:
	lea si,  Display_messageL
	jmp lblwtdprint
	
lblwtdM:
	lea si,  Display_messageM
	jmp lblwtdprint

lblwtdN:
	lea si,  Display_messageN
	jmp lblwtdprint

lblwtdO:
	lea si,  Display_messageO
	jmp lblwtdprint

lblwtdP:
	lea si,  Display_messageP
	jmp lblwtdprint

lblwtdR:
	lea si,  Display_messageR
	jmp lblwtdprint

lblwtdS:
	lea si,  Display_messageS
	jmp lblwtdprint

lblwtdT:
	lea si,  Display_messageT
	jmp lblwtdprint

lblwtdU:
	lea si,  Display_messageU
	jmp lblwtdprint
	
lblwtdV:
	lea si,  Display_messageV
	jmp lblwtdprint
	
lblwtdX:
	lea si,  Display_messageX
	jmp lblwtdprint
	
lblwtdZ:
	lea si,  Display_messageZ
	jmp lblwtdprint
	
;podaci su spremni, u registrima si i dx, treba pozvati proc za ispis
lblwtdprint:
	call PrintOneAsciiChar
	;pomeranje u matrici
	add dx, 10
	dec cx
	jz lblprintend ;; zavrsili smo sa ispisom, izlazimo iz procedure
	jmp lblwritetextondisplay  ;; vracamo se na pocetak
	
	
lblprintend:	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
PrintDisplay ENDP

;********************************************************************************
;	ReadKey - ceka da se pritisne taster na tastaturi
;   softverski prekid na ulazu 16h, sa argumentom 10h kroz AH
;		Input :	nema
;		Output :	al - ASCII kod pritisnutog tastera
;					ah - scan code tastera
;********************************************************************************
ReadKey PROC
	push cx
	mov ah, 10h
	int 16h
	
	;izlazak u slucaju ESC
	cmp al, charExit;
	jnz lblRKSkip;
	call Timer_deinit
	call Exit;
	
lblRKSkip:	
	pop cx
	ret
ReadKey ENDP


;********************************************************************************
;	StringCopy - kopiranje jednog stringa na drugi
; **** probati izmeniti i odraditi sa instrukcijama za stringove ***********
;		Input : 	si - offset stringa iz koga se vrsi kopiranje
;					di - offset stringa u ukoji se vrsi kopiranje
;					bx - pozicija u destination stringu na koju se pocinje kopiranje
;					cx - broj karkatera koje treba iskopirati
;		Output :	nema
;********************************************************************************
StringCopy PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	add di, bx
	
	
stringCopyLoop:
	xor al, al
	mov al, [si]
	mov [di], al
	inc si
	inc di
	loop stringCopyLoop
	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
StringCopy ENDP

;********************************************************************************
;	StringCopyLeft - kopiranje jednog stringa na drugi, zanemarivanje razmaka
; **** probati izmeniti i odraditi sa instrukcijama za stringove ***********
;		Input : 	si - offset stringa iz koga se vrsi kopiranje
;					di - offset stringa u ukoji se vrsi kopiranje
;					bx - pozicija u destination stringu na koju se pocinje kopiranje
;					cx - broj karkatera koje treba iskopirati
;		Output :	nema
;********************************************************************************
StringCopyLeft PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	add di, bx
	
	
stringCopyLeftLoop:
	xor al, al
	mov al, [si]
	cmp al, 20h ; space
	jz lblCopyLeftSkip
	mov [di], al
	inc di
lblCopyLeftSkip:
	inc si
	loop stringCopyLeftLoop
	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
StringCopyLeft ENDP

;********************************************************************************
;	StringCopyExtended - kopiranje jednog stringa na drugi
;		Input : 	si - offset stringa iz koga se vrsi kopiranje
;					di - offset stringa u ukoji se vrsi kopiranje
;					bx - pozicija u destination stringu na koju se pocinje kopiranje
;					cx - broj karkatera koje treba iskopirati
;					dx - pozicija u source stringu odakle se pocinje kopiranje
;		Output :	nema
;********************************************************************************
StringCopyExtended PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	add di, bx
	
	; samo je ovo novo:
	add si, dx
	
stringCopyExtLoop:
	xor al, al
	mov al, [si]
	mov [di], al
	inc si
	inc di
	loop stringCopyExtLoop
	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
StringCopyExtended ENDP

;*****************************************************************
;	FlushString - prazni sadrzaj stringa
;	Postavlja sve karaktere na znak space osim poslednjeg koji je $
;		Input:	bx - offset stringa koga treba isprazniti
;				cx - duzina stringa
;		Output:	nema
;*****************************************************************
FlushString PROC
	push bx
	push cx
	push dx
	push si
	
	mov dl, 20h  ; ascii space
	xor si, si
	moreChars:
		mov [bx][si], dl
		inc si
		loop moreChars
		
	pop si
	pop dx
	pop cx
	pop bx
	ret
FlushString ENDP


;***************************************************************************
;	 ByteToString - konvertuje bajt u string
;		Input :	al - bajt koji se konvertuje u string
;		Output:	String_Rezultat - niz karaktera koji predstavlja bajt
;***************************************************************************
ByteToString PROC	
	push cx
	push di
	push bx
	push ax			; u ah div instrukcija smesta rezultat pa i ovaj registar mora da se sacuva
	
	mov bx, offset String_Rezultat
	mov cx, 10
	call FlushString
	
	mov cx, 0003h	; u bajtu mogu da postoje maksimalno tri cifre
	mov di, 09h		; indeks niza OutputStringBuffer; niz se popunjava od poslednjeg elementa
	xor bx, bx
	mov bl, 0Ah		; delilac je 10 decimalno ili 0A hex

	moreByte :	
			div bl
			add ah, 30h ; 30h je ASCII za 0
			mov String_Rezultat[di], ah
			xor ah, ah
			dec di
			cmp al, 0h
			jnz moreByte
	
	pop ax
	pop bx
	pop di
	pop cx
	
	ret	
ByteToString ENDP

;***************************************************************************
;	 WordToString - konvertuje bajt u string
;		Input :	ax - word koji se konvertuje u string
;		Output:	String_Rezultat - niz karaktera koji predstavlja word
;***************************************************************************
WordToString PROC	
	push dx			; u registar dx se smesta ostatak od deljenja
	push cx
	push di
	push bx
	push ax
	
	mov bx, offset String_Rezultat
	mov cx, 10
	call FlushString
	
	mov cx, 0005h	; u wordu mogu da postoje maksimalno pet cifre
	mov di, 09h		; indeks niza OutputStringBuffer; niz se popunjava od poslednjeg elementa
	mov bx, 0Ah		; delilac je 10 decimalno ili 0A hex

	moreWord1:	
			xor dx, dx
			div bx
			add dl, 30h
			mov String_Rezultat[di], dl
			dec di
			cmp ax, 0h
			jnz moreWord1
	
	pop ax
	pop bx
	pop di
	pop cx
	pop dx
	
	ret	
WordToString ENDP




;**************************************************************************
; Kod nove prekidne rutine za tajmer (tajmer otkucava na 55ms)
; 18*55ms = 990ms ~ 1s
; broj otkucaja se pamti u globalnoj promenljivoj ticks_in_timer_count
;	Input - n/a
;	Output - n/a
;**************************************************************************

new_timer_routine proc far
	push ax
	push ds
	push es
	push di
	
	mov ax, _DATA   ;data segment
	mov ds, ax

	
	mov al, ticks_in_timer_count
	inc al
	mov ticks_in_timer_count, al
	cmp al, 18
	jnz lblEndTimer  ; ako nije izbrojano 18 tickova, skacemo na kraj procedure
	xor al, al  ; al = 0
	mov ticks_in_timer_count, al  ; ticks_in_timer_rout = 0
	
	
	call UpdateClock  ; azuriramo celobrojne vrednosti za vreme
	
	;osvezicemo ekran samo kad treba
	mov al, stanje
	cmp al, stanje_spreman
	jz lblTimerPrint
	cmp al, stanje_zauzet
	jnz lblEndTimer
lblTimerPrint:
	call PrintDisplay
	

lblEndTimer:
	
	pop di
	pop es
	pop ds
	pop ax

	iret
new_timer_routine endp

;****************************************************************
; Azuriranje sata
; 	Input - n/a
;	Output - n/a
;****************************************************************

UpdateClock PROC NEAR	

	INC CLOCK_SECONDS
	CMP CLOCK_SECONDS, 60
	JNE	UpdateClock_end
	
	mov CLOCK_SECONDS, 0
	INC CLOCK_MINUTES
	CMP CLOCK_MINUTES, 60
	JNE UpdateClock_end
	
	MOV CLOCK_MINUTES, 0
	INC CLOCK_HOURS
	CMP CLOCK_HOURS, 24
	JNE UpdateClock_end
	
	MOV CLOCK_HOURS, 0
	
UpdateClock_end:	

  RET
UpdateClock ENDP


;********************************************************************************
;	SendTimeToDisplayString - upisivanje vremena u Diplay_Poruka
;		Input : 	nema
;		Output :	nema
;********************************************************************************
SendTimeToDisplayString PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	mov al, boolDisplayTime
	cmp al, 1
	jnz finishSendTimeToDspForw   ; ako ne treba da ispisemo vreme na displayu, izlazimo is procedure
	jmp lblTreabaDaMenjamo
	
finishSendTimeToDspForw:	jmp finishSendTimeToDsp
	
lblTreabaDaMenjamo:
	; flush output string
	xor bx, bx
	mov bx, offset String_Rezultat
	mov cx, 10
	call FlushString
	
	; flush display string
	mov bx, offset Diplay_Poruka
	mov cx, 17  
	call FlushString
	
	;;;===================
	; glavna obrada procedure
	xor ax, ax
	xor bx, bx
	; prvo sate
	mov bl, CLOCK_HOURS
	cmp bl, 9
	jg dvocifreniSati
	
	; ovde jednocifreni
	; prvo cemo da upisemo jednu nulu
	mov si, offset msgConst0
	mov di, offset Diplay_Poruka
	mov bx, 3
	mov cx, 1
	call StringCopy ; upisana nula
	; ne treba, upisujemo posle u bx; ovo ne treba: inc bx ; upisali smo jednu cifru, pomeramo pokazivac da bi odavde upisali narednu cifru
	
	mov al, CLOCK_HOURS  ; ByteToString trazi u al ono sto treba da konvertuje
	call ByteToString  
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 4
	mov cx, 1
	mov dx, 9  ; poslednji karakter iz String_Rezultat
	call StringCopyExtended
	
	jmp lblMinuti
	
dvocifreniSati:
	mov al, CLOCK_HOURS  ; ByteToString trazi u al ono sto treba da konvertuje
	call ByteToString  
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 3
	mov cx, 2
	mov dx, 8  ; pretposlednji karakter iz String_Rezultat
	call StringCopyExtended

lblMinuti:

	
	;; sad idu minuti
	mov bl, CLOCK_MINUTES
	cmp bl, 9
	jg dvocifreniMinuti
	
	; ovde jednocifreni
	; prvo cemo da upisemo jednu nulu
	mov si, offset msgConst0
	mov di, offset Diplay_Poruka
	mov bx, 6
	mov cx, 1
	call StringCopy ; upisana nula
	
	
	mov al, CLOCK_MINUTES  ; ByteToString trazi u al ono sto treba da konvertuje
	call ByteToString  
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 7
	mov cx, 1
	mov dx, 9  ; poslednji karakter iz String_Rezultat
	call StringCopyExtended
	
	jmp lblSekunde
	
dvocifreniMinuti:
	mov al, CLOCK_MINUTES  ; ByteToString trazi u al ono sto treba da konvertuje
	call ByteToString  
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 6
	mov cx, 2
	mov dx, 8  ; pretposlednji karakter iz String_Rezultat
	call StringCopyExtended
	
	
	
	
lblSekunde:

	
	;; sad idu sekunde
	mov bl, CLOCK_SECONDS
	cmp bl, 9
	jg dvocifreneSekunde
	
	; ovde jednocifreni
	; prvo cemo da upisemo jednu nulu
	mov si, offset msgConst0
	mov di, offset Diplay_Poruka
	mov bx, 9
	mov cx, 1
	call StringCopy ; upisana nula
	
	
	mov al, CLOCK_SECONDS  ; ByteToString trazi u al ono sto treba da konvertuje
	call ByteToString  
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 10
	mov cx, 1
	mov dx, 9  ; poslednji karakter iz String_Rezultat
	call StringCopyExtended
	
	jmp finishSendTimeToDsp
	
dvocifreneSekunde:
	mov al, CLOCK_SECONDS  ; ByteToString trazi u al ono sto treba da konvertuje
	call ByteToString  
	mov si, offset String_Rezultat
	mov di, offset Diplay_Poruka
	mov bx, 9
	mov cx, 2
	mov dx, 8  ; pretposlednji karakter iz String_Rezultat
	call StringCopyExtended

finishSendTimeToDsp:	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
SendTimeToDisplayString ENDP

;********************************************************************************
;	PrintOneAsciiChar - ispisivanje jednog karaktera na displayu
;		Input : 	dx - pocetna tacka matrice odakle se pocinje ispisivanje (pomnoziti sa 2 zbog data/pref)
;					si - offset podmatrice koju zelimo da ispisemo
;		Output :	nema
;********************************************************************************
PrintOneAsciiChar PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	
	;; -- upisivanje u es pocetne adrese video memorije --
	push ax
	mov ax, 0B800h
	mov es, ax
	pop ax
	
	xor bx, bx  ;; resetujemo bx -> sluzice nam za x * 80
spoljas:
	mov ax, 160   ;; 80 x 2 (podatak + prefs)
	mul bl
	add ax, dx  ;; ax = pocetak + 80*b  (b je redni broj vrste)
	
	mov di, ax;
	mov cx, 5 ; bice iterator, toliko kolona imamo (5x5 matrica)
	
	;;test
	mov ah, 0Ah  ; svetlo zeleno
	
unutras:
	mov al, [si]
	mov es:[di], ax
	inc di
	inc di
	inc si
	loop unutras
	
	; -- treba da sredimo i spoljasnju petlju
	inc bx
	cmp bx, 5
	jne spoljas
	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
PrintOneAsciiChar ENDP

;********************************************************************************
;	AddStringToSerial - dodavanje novog stringa na serijski (i izbacivanje poslednjeg - FIFO)
;		Input : 	si - offset stringa koga zelimo da dodamo
;		Output :	nema
;********************************************************************************
AddStringToSerial PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	push si ; kasnije cemo da ga skinemo i iskoristimo

	mov ax, _DATA
	mov ds, ax
	
	
	xor cx, cx
	xor bx, bx
	mov cl, serial_messageWidth
	
	mov si, offset serial_message13
	mov di, offset serial_message14
	call StringCopy
	
	mov si, offset serial_message12
	mov di, offset serial_message13
	call StringCopy
	
	mov si, offset serial_message11
	mov di, offset serial_message12
	call StringCopy
	
	mov si, offset serial_message10
	mov di, offset serial_message11
	call StringCopy
	
	mov si, offset serial_message09
	mov di, offset serial_message10
	call StringCopy
	
	mov si, offset serial_message08
	mov di, offset serial_message09
	call StringCopy
	
	mov si, offset serial_message07
	mov di, offset serial_message08
	call StringCopy
	
	mov si, offset serial_message06
	mov di, offset serial_message07
	call StringCopy
	
	mov si, offset serial_message05
	mov di, offset serial_message06
	call StringCopy
	
	mov si, offset serial_message04
	mov di, offset serial_message05
	call StringCopy
	
	mov si, offset serial_message03
	mov di, offset serial_message04
	call StringCopy
	
	mov si, offset serial_message02
	mov di, offset serial_message03
	call StringCopy
	
	mov si, offset serial_message01
	mov di, offset serial_message02
	call StringCopy
	
	mov si, offset serial_message00
	mov di, offset serial_message01
	call StringCopy
	
	pop si  ;  ovde je offset stringa koji treba da dodamo
	mov di, offset serial_message00
	call StringCopy
	
	
	; na kraju ispisemo nove stringove
	call PrintSerialStrings
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
AddStringToSerial ENDP

;********************************************************************************
;	PrintSerialStrings - ispisivanje stringova iz komunikacije sa racunarom preko serijskog porta
;		Input : 	nema
;		Output :	nema
;********************************************************************************
PrintSerialStrings PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	xor cx, cx
	
	mov dx, 1282 ;  8. red, uz levu ivicu
	mov ah, 0Fh ; bela
	mov cl, serial_messageWidth
	mov si, offset serial_message00
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message01
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message02
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message03
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message04
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message05
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message06
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message07
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message08
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message09
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message10
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message11
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message12
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message13
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset serial_message14
	call PrintTextOnConsole
	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
PrintSerialStrings ENDP

;********************************************************************************
;	AddStringToBill - dodavanje novog stringa na racun (i izbacivanje poslednjeg - FIFO)
;		Input : 	si - offset stringa koga zelimo da dodamo
;		Output :	nema
;********************************************************************************
AddStringToBill PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	push si ; kasnije cemo da ga skinemo i iskoristimo

	mov ax, _DATA
	mov ds, ax
	
	
	xor cx, cx
	xor bx, bx
	mov cx, printer_messageWidth
	
	;shiftujemo
	mov si, offset printer_message13
	mov di, offset printer_message14
	call StringCopy
	
	mov si, offset printer_message12
	mov di, offset printer_message13
	call StringCopy
	
	mov si, offset printer_message11
	mov di, offset printer_message12
	call StringCopy
	
	mov si, offset printer_message10
	mov di, offset printer_message11
	call StringCopy
	
	mov si, offset printer_message09
	mov di, offset printer_message10
	call StringCopy
	
	mov si, offset printer_message08
	mov di, offset printer_message09
	call StringCopy
	
	mov si, offset printer_message07
	mov di, offset printer_message08
	call StringCopy
	
	mov si, offset printer_message06
	mov di, offset printer_message07
	call StringCopy
	
	mov si, offset printer_message05
	mov di, offset printer_message06
	call StringCopy
	
	mov si, offset printer_message04
	mov di, offset printer_message05
	call StringCopy
	
	mov si, offset printer_message03
	mov di, offset printer_message04
	call StringCopy
	
	mov si, offset printer_message02
	mov di, offset printer_message03
	call StringCopy
	
	mov si, offset printer_message01
	mov di, offset printer_message02
	call StringCopy
	
	mov si, offset printer_message00
	mov di, offset printer_message01
	call StringCopy
	
	pop si  ;  ovde je offset stringa koji treba da dodamo
	mov di, offset printer_message00
	call StringCopy
	
	
	; na kraju ispisemo nove stringove
	call PrintBillStrings
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
AddStringToBill ENDP

;********************************************************************************
;	PrintBillStrings - ispisivanje stringova sa racuna
;		Input : 	nema
;		Output :	nema
;********************************************************************************
PrintBillStrings PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	

	xor cx, cx
	
	mov dx, 1398  ;  8. red, uz desnu ivicu
	mov ah, 0Fh ; bela boja
	mov cx, printer_messageWidth
	mov si, offset printer_message14
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message13
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message12
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message11
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message10
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message09
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message08
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message07
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message06
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message05
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message04
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message03
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message02
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message01
	call PrintTextOnConsole
	
	add dx, 160
	mov si, offset printer_message00
	call PrintTextOnConsole
	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
PrintBillStrings ENDP

;********************************************************************************
; PrintSignature - ispisuje potpis
;		Input: nema
;		Output: nema
;
;********************************************************************************

PrintSignature PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	

	xor cx, cx
	
	mov dx, 3680 ;pretposlednji red, uz levu ivicu
	mov ah, 07h ; siva boja
	mov cx, 80
	mov si, offset msgSigSeparator
	call PrintTextOnConsole
	
	mov dx, 3842  ;  poslednji red, uz levu ivicu
	mov ah, 07h ; siva boja
	mov cx, 68
	mov si, offset msgSignature
	call PrintTextOnConsole
	

	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
PrintSignature ENDP

;********************************************************************************
;	SearchRecords - pretrazuje evidenciju za da trazenu sifru iz ax
;		Input : 	ax - sifra koju trazimo
;		Output :	nema (globalne promenljive - stringovi i sl.)
;********************************************************************************
SearchRecords PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	shl ax, 4 ; mnozenje sifre zapamcene u al sa 16
	add ax, offset evidencija
	; sad cemo da iskopiramo iz evidnecije potrebne stvari
	mov si, ax  ; tu je offset evidencije
	mov di, offset imeProizvoda
	xor bx, bx
	mov cx, 12
	call StringCopy
	
	add si, 12
	mov dx, [si]
	mov jedinicnaCena, dx


lblSRKraj:	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
SearchRecords ENDP

;********************************************************************************
;	WaitWait - radi busy wait 1 (ili 3) sekunde
;		Input : 	nema
;		Output :	nema
;********************************************************************************
WaitWait PROC
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	xor bx, bx
	xor ax, ax
	
	mov bl, CLOCK_SECONDS
	add bl, 3
	
	; if (bl > 59) { bl = 2; }
	cmp bl, 59
	jl lblWWstillWait  ; skip next instruction
	mov bl, 2
	
lblWWstillWait:
	mov al, CLOCK_SECONDS
	cmp al, bl
	jnz lblWWstillWait


lblWWKraj:	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	ret
WaitWait ENDP

;********************************************************************************
;	PrintTextOnConsole - ispisivanje stringa u display matrici (80x25)
;		Input : 	dx - pocetna tacka matrice odakle se pocinje ispisivanje (pomnoziti sa 2 zbog data/pref)
;					ah - boja
;					si - offset stringa koji zelimo da ispisemo
;					cx - duzina stringa
;		Output :	nema
;********************************************************************************
PrintTextOnConsole PROC
	cli
	push ax
	push bx
	push dx
	push es
	push cx
	push si
	push di
	
	
	;; -- upisivanje u es pocetne adrese video memorije --
	push ax
	mov ax, 0B800h
	mov es, ax
	pop ax
	
	
	mov di, dx
	
josKarakteraZaIspis:
	mov al, [si]
	mov es:[di], ax ;u AH je boja, u AL vrednost
	inc di
	inc di
	inc si
	loop josKarakteraZaIspis	
	
	
	pop di
	pop si
	pop cx
	pop es	
	pop dx
	pop bx
	pop ax
	sti
	ret
PrintTextOnConsole ENDP

;****************************************
;	DisableCursorBlinking - iskljucuje blinkovanje kursora (u gornjem levom uglu)
;****************************************
DisableCursorBlinking PROC
	push ax
	push cx
	
	mov ah, 01h
	mov cx, 2000h
	int 10h
	
	pop cx
	pop ax
	ret
DisableCursorBlinking ENDP

;****************************************
;	DrawScreen - procedura koja iscrtava ceo ekran
;	Input - n/a
;	Output - n/a
;****************************************
DrawScreen PROC
	push ax
	push cx
	
	call PrintDisplay
	
	
	call PrintBillStrings
	call PrintSerialStrings
	
	pop cx
	pop ax
	ret
DrawScreen ENDP



;********************************************************************************
;	Exit - izlazak iz programa i povratak u DOS
;		Input : 	nema
;		Output :	nema
;********************************************************************************
Exit PROC
	mov ah, 4ch
	mov al, 00h
	int 21h
Exit ENDP

;************************************************************
;	glavni program
;************************************************************
Main:
	mov ax, _DATA
	mov ds, ax
	;--------------------------------------------------
	;	init video mod
	;	koristi se 80x25 Color Text
	;--------------------------------------------------
	mov ah, 00h
	mov al, 03h
	int 10h
	
	
	
	call Timer_init
	call DrawScreen
	call DisableCursorBlinking
	
	call PrintSignature
	

	call ProgramLoop
	call Timer_deinit
	call Exit
end Main